﻿#!/usr/bin/env python3

#函数 2016-1-8 17:13:13

# 1.调用内置函数

import math

a = abs(-100);#绝对值
maxVal = max(1,20);#返回较大的数
hexVal = hex(16); #转换成16进制
print(a,maxVal,hexVal);

# 2.定义函数

def traceArr(arr): #同样的冒号和缩进不能少
	for i in arr:
		print("i=",i);
	print("调用完traceArr函数了;");
	return "traceArr";

funcName = traceArr([1,"aa",20,"23"]); #先定义才能调用,不能在定义之前调用
print("funcName=",funcName);

#定义空函数

def emptyFunc():
	pass; #什么都不做,只是定义看而已,其他语句也可以添加pass

emptyFunc();

#数据类型检查可以用内置函数isinstance(obj,class)实现class可以是一个set
s = "hello";
flag = isinstance(s,(int,float)); #第二个参数可以是一个set
print(flag);

def getPos(x,y):
	return x,y; #可以返回最多两个数和lua一样
	
x,y =getPos(10,20)
print("x,y=",x,y,getPos(10,20))

x = 10+math.cos(math.pi/60)*10 #同样是用弧度
y = 10+math.sin(math.pi/60)*10
print("x,y=",x,y)

#函数参数
#参数定义的顺序必须是：必选参数、默认参数、可变参数/命名关键字参数和关键字参数。
#求x的n次方的函数,py支持默认参数
def power(x,n=2):
	product = 1;
	while n>0:
		n = n - 1;
		product = product*x;
	return product;

print("2的8次方=",power(2,8));

def add_end(list=[]):
	list.append("end")
	return list;

#默认参数的坑
print(add_end());#得到 [end]
print(add_end());#得到 ['end','end']
#这里和as3非常不一样,每次调用存放list的对象是随着调用而变的而且是指向同一地址
#所以默认参数一定要用不可变对象，如果是可变对象，程序运行时会有逻辑错误！

#可变参数,在参数前面加*就可以了,参数会被当做是一个tuple
def count(*nums):
	count=0;
	for i in nums:		
		count = count+ i;
	print("count=",count);

count(1,25,8,15,45);
args = [10,20,50];
count(*args);#把数组当做多个参数;解包裹

#关键字参数,在参数前面加**就可以了,参数会被当做是一个dict
def regist(name,age,**kw):
	print(kw);


regist("jack",20,city="gz",sex='F');#关键字参数必须传键值对,所有键值对参数在函数背包会放进一个dict里面

ext = {'city':'zj','sex':'f','h':170};#dict的键名必须用引号括起来
regist("jack",20,**ext);#解包裹 字典dict的解包裹和list列表的解包裹不同 看78行

#命名参数,只接收特定字段的关键字参数;

def person(name,*,city,jop): #*后的字段名就是可以接收的字段名
	print(name,city,jop);

person("jet",city='gz',jop='coder');#命名参数也是必须要传键值对

def person(name,*,city='gz',jop): #*后的字段名就是可以接受的字段名
	print(name,city,jop);
	
person("jet",jop='coder'); #city有默认值可以不传

#神奇地调用函数
def f1(a,b,c,*,name,city,**kw):#注意命名参数后面不能跟*list这样的可变参数类型,但是可以跟**kw关键字参数
	print("a,b,name,city,arr,kw=",a,b,name,city,kw);

f1(1,2,3,name='kfz',city='gz',age=20,jop='coder'); #正常调用和传入参数

args = [10,20,30];
d1 = {'name':"kfz","city":"zj",'jop':'coder'};
#神奇的地方就是这里了,args会被当做是前面三个参数,d1会被当做是命名参数的name和city还有关键字参数
f1(*args,**d1);#其实无论何种参数类型都可以用这个方式调用

#求N的阶乘
def factorial(n):
	res =  1
	for i in range(1,n+1):		
		res = res*i	
	return res

#print(factorial(10))

def sumFactorial(n):
	sum=0;
	s="";
	for i in range(1,n+1):
		sum = sum+factorial(i)
		s = s + '+' +str(i)+"!"
	s = s[1:len(s)]+"="+str(sum)
	print(s)
	return sum
	
sumFactorial(10)
'''
匿名函数: lambda
python 使用 lambda 来创建匿名函数。
lambda只是一个表达式，函数体比def简单很多。
lambda的主体是一个表达式，而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
lambda函数拥有自己的命名空间，且不能访问自有参数列表之外或全局命名空间里的参数。
虽然lambda函数看起来只能写一行，却不等同于C或C++的内联函数，后者的目的是调用小函数时不占用栈内存从而增加运行效率

lambda [arg1 [,arg2,.....argn]]:expression

'''
#排序函数
lst = ["google","baidu","tencent","taobao"]
print(sorted(lst,key=lambda x:x[1],reverse=True)) #降序(从大到小)


